using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FernUniHagen.CompilerExtension.Functions;
using FernUniHagen.CompilerExtension.DataStructures;
using FernUniHagen.CompilerExtension.Attributes;
using Roslyn.Compilers.Common;
using Roslyn.Compilers.CSharp;

namespace FernUniHagen.CompilerExtension.Converter.Block
{
    public class ArgumentSyntaxConverter : BlockNodeFactory
    {
        public override List<StatementSyntax> ConvertBlockNode()
        {
            return Strip();
        }

        private List<StatementSyntax> Strip()
        {
            var statementsToAdd = new List<StatementSyntax>();

            
            var argument = NodeToReplaceInBlock.ReferencedNode.FirstAncestorOrSelf<ArgumentSyntax>();



            var newArgument = argument;
            
            if (argument.Expression is IdentifierNameSyntax)
            {
                var argumentIdentfier = Utilities.CastNode<IdentifierNameSyntax>(argument.Expression);
                CommonSyntaxNode argumentDefinition = SemanticModel.FindDecleration(argumentIdentfier);
                if (argumentDefinition != null)
                {
                   
                    AttributeType argumentDefinitionMultiplicity = AttributeType.None;
                    GenericNameSyntax genericType = null;
                    Utilities.GetMultiplicityAttribute(argumentDefinition, out argumentDefinitionMultiplicity, out genericType);
                    var roslynVariable = VariableCreatorService.GetTempVariable();
                    //Realizes Parameter Passes
                    if (argumentDefinitionMultiplicity == AttributeType.Any || argumentDefinitionMultiplicity == AttributeType.Option)
                    {
                        StatementSyntax initList = null;
                        StatementSyntax assignList = null;
                        switch (argumentDefinitionMultiplicity)
                        {
                            case AttributeType.Any:
                                initList = Syntax.ParseStatement(string.Format("{0} {1} = new {0}();" + Environment.NewLine, genericType.ToString(), roslynVariable));
                                break;
                            case AttributeType.Option:
                                VariableDeclarationSyntax declaredVariable =
                                    (VariableDeclarationSyntax)argumentDefinition.DescendantNodes().First(n => n is VariableDeclarationSyntax);
                                initList = Syntax.ParseStatement(string.Format("{0} {1};" + Environment.NewLine, declaredVariable.Type.ToString(), roslynVariable));
                                break;
                        }
                        //TODO: Needs to be translated
                        assignList = Syntax.ParseStatement(string.Format("{0} = {1};" + Environment.NewLine, roslynVariable, argumentIdentfier.ToString()));
                        newArgument = Syntax.ParseArgumentList(roslynVariable).DescendantNodesAndSelf().First(n => n is ArgumentSyntax) as ArgumentSyntax;
                        statementsToAdd.AddRange(initList, assignList);

                    }
                    
                }
               

            }

            StatementReplacements = new StatementReplacement<CommonSyntaxNode>(NodeToReplaceInBlock.ReferencedNode, argument);
        //    StatementReplacements.Add(new StatementReplacement(NodeToReplaceInBlock.ReferencedNode, argument));
            return statementsToAdd;
        }

        
    }
}
